package com.jackrain.nea.shiro.stateless;

import com.alibaba.fastjson.JSONException;
import com.alibaba.fastjson.JSONObject;
import com.jackrain.nea.exception.NDSException;
import com.jackrain.nea.web.query.QueryUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.web.filter.AccessControlFilter;
import org.apache.shiro.web.servlet.ShiroHttpServletRequest;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.text.ParseException;
import java.util.Date;

/**
 * 控制并发人数
 * Created by kunlun on 2016/7/26.
 */
@Slf4j
public class StatelessAccessControlFilter extends AccessControlFilter {

    private static Logger logger= LoggerFactory.getLogger(StatelessAccessControlFilter.class.getName());

    protected boolean isAccessAllowed(ServletRequest request, ServletResponse response, Object mappedValue) throws Exception {
        return false;
    }
    protected boolean onAccessDenied(ServletRequest request, ServletResponse response) throws Exception {
        try{
            //1、客户端传入的用户身份
            String accessKey = ((ShiroHttpServletRequest) request).getHeader("accessKey");
            if(accessKey == null || accessKey.length() <= 0){
                throw new NDSException("账号不允许为空");
            }
            //2、客户端生成的消息摘要
            String sign = ((ShiroHttpServletRequest) request).getHeader("sign");
            if(sign == null || sign.length() <= 0){
                throw new NDSException("签名不允许为空");
            }
            //3、客户端传入的时间
            String dateTime = ((ShiroHttpServletRequest) request).getHeader("dateTime");
            if(dateTime == null || sign.length() <= 0){
                throw new NDSException("时间不允许为空");
            }

            Date date = QueryUtils.dateTimeSecondsFormatter.parse(dateTime);
            long timeSpend = System.currentTimeMillis() - date.getTime();
            if(timeSpend/(1000.00*60*5) > 5){
                throw new NDSException("签名已过期");
            }

            //3、客户端请求的参数列表
            String params = ((ShiroHttpServletRequest) request).getHeader("params");
            JSONObject jo = JSONObject.parseObject(params);
            if(params != null && jo == null){
                throw new NDSException("参数格式错误");
            }
            //4、生成无状态Token
            StatelessToken token = new StatelessToken(accessKey,dateTime,sign,jo);
            getSubject(request, response).login(token);

        }catch(ParseException e) {
            onLoginFail(response,"时间格式错误"); //6、登录失败
            return false;
        }catch(JSONException e){
            onLoginFail(response,"参数json格式错误"); //6、登录失败
            return false;
        } catch(Exception e){
            onLoginFail(response,e.getMessage()); //6、登录失败
            return false;
        }
        return true;
    }
    //登录失败时默认返回401状态码
    private void onLoginFail(ServletResponse response,String message) throws IOException {
        HttpServletResponse httpResponse = (HttpServletResponse) response;
        httpResponse.setHeader("Content-type", "text/html;charset=UTF-8");
        httpResponse.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
        try {
            httpResponse.getWriter().write(message);
        } catch (IOException e) {
            log.error(e.getMessage(),e);
        }
    }
}
